#include <stdlib.h>

#include "lib.h"
#include "kenosql.h"
#include "kenogame.h"
#include "kenobet.h"
#include "kenocard.h"
#include "odbc.h"
#include "missinggamenums.h"

KenoSQL::KenoSQL(TrackSQL* tracker)
{
    //We're going to assume this pointer is always valid
    ASSERT( tracker );

    this->tracker = tracker;
#ifdef USE_MISSINGGAMENUMS
	//missing game nums deleted in TrackSQL::~TrackSQL
	missinggamenums = new MissingGameNums(this, "pub_getTableIdentityKeno");
#endif
}

int32
KenoSQL::createGame(int32 casinoId,
	const PID& pid, bool8 forMoney, SESSIONID sessionId, int32 compFactor,
	KenoGameID gid, int32* balance, int32* comp, KenoBet *bet, int32 numGames, bool8 newGroup)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

	conn = tracker->getConn();
	if (!conn)
        return TrackSQL::NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_CreateGameKeno ");
		query->addParam(casinoId);
		query->addParam(pid);
		query->addParam((bool8)(forMoney != 0));
		query->addParam(sessionId, ODBCQuery::NOQUOTES);
		query->addParam(compFactor);
		query->addParam(bet->GetTotalBet(), ODBCQuery::MONEY);
		query->addParam(numGames);
		query->addParam((bool8)newGroup);

		if (query->exec())
		{
			while (query->getRow())
			{
				ok =
					query->getData(1, gid, KENO_GAMEID_SIZE) &&
					query->getData(2, balance, ODBCQuery::MONEY) &&
					query->getData(3, comp);
			}
		}
		delete query;
	}

	if (ok)
	{
		#ifdef USE_MISSINGGAMENUMS
		int32 gamenum = atol(gid);
		if (missinggamenums)
				missinggamenums->setGameNum(gamenum);
		#endif
	}

	if(ok)
	{
		KenoCard *card;
		int32 cardid=0;
		int32 pickid=0;

		// now add all the keno cards to the database
		for(int32 i = 0; i < bet->GetNumCards(); i++)
		{
			card = bet->GetCard(i);
			if(!card)
			{
				ok = false;
				break;
			}

			query = conn->query();
			if(query)
			{
				query->define("exec pub_KenoCreateCard ");
				query->addParam(gid, ODBCQuery::NOQUOTES);
				query->addParam(card->GetCost(), ODBCQuery::MONEY);

				if (query->exec())
				{
					while (query->getRow())
						ok = query->getData(1, &cardid);
				}
			}
			delete query;

			if(!ok)	break;

			for(int32 j = 0; j < card->GetNumPicks(); j++)
			{
				// and add the keno picks to the database
				query = conn->query();
				if(query)
				{
					query->define("exec pub_KenoAddPick ");
					query->addParam(cardid);
					query->addParam(card->GetPick(j));

					if (query->exec())
					{
						while (query->getRow())
							ok = query->getData(1, &pickid);
					}
				}
				delete query;

				if(!ok) break;

			}

			if(!ok) break;
		}
	}

	delete conn;

	return ok ? TrackSQL::NoError : TrackSQL::ExecFailed;
}

int32
KenoSQL::gameDone(int32 casinoId, const PID& pid, bool8 forMoney, KenoGameID gid,
	int32 balanceAdjust, int32* balance, int32* comp, int32 *kenoresults)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

	conn = tracker->getConn();
	if (!conn)
		return TrackSQL::NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_KenoGameDone ");
		query->addParam(casinoId);
		query->addParam(pid);
		query->addParam((bool8)(forMoney != 0));
		query->addParam(gid, ODBCQuery::NOQUOTES);

		// add the picks
		for(int32 i = 0; i < 20; i++)
		{
			query->addParam(kenoresults[i]);
		}

		query->addParam(balanceAdjust, ODBCQuery::MONEY);

		if (query->exec())
		{
			while (query->getRow())
			{
				ok = query->getData(1, balance, ODBCQuery::MONEY) &&
					query->getData(2, comp);
			}
		}
		delete query;
	}

	delete conn;

	return ok ? TrackSQL::NoError : TrackSQL::ExecFailed;
}

int32
KenoSQL::getPayTable(uint8 *paytable)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

	*paytable = 0;

	conn = tracker->getConn();
	if (!conn)
		return TrackSQL::NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_KenoGetOptions");
		if (query->exec())
		{
			while (query->getRow())
			{
				ok = query->getData(1, paytable);
			}
		}
		delete query;
	}

	delete conn;

	return ok ? TrackSQL::NoError : TrackSQL::ExecFailed;
}

int32
KenoSQL::getPlayerLimits(const PID& pid, int32 gameId, uint8 machId,
	int32* compFactor)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

	conn = tracker->getConn();
	if (!conn)
		return TrackSQL::NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_lim_getPlayerLimits ");
		query->addParam(pid);
		query->addParam(gameId);
		query->addParam(machId, ODBCQuery::BINARY);

		if (query->exec())
		{
			while (query->getRow())
			{
				ok = query->getData(4, compFactor);
			}
		}
		delete query;
	}
	delete conn;

	return ok ? tracker->isGameEnabled(gameId,machId) : TrackSQL::ExecFailed;
}

//psharpless  11/3/06  case#: 16436
//Keno denomination amounts are no longer hard coded
int32
KenoSQL::getDenominations(int32 *DenomValues)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

    localCurrency lc;

	ok = tracker->getLocale(&lc) == TrackSQL::NoError;

    if (!ok)
    {
        return ok;
    }

	conn = tracker->getConn();
	if (!conn)
		return TrackSQL::NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_KenoGetDenominations ");
        query->addParam(lc.int_curr_symbol);

		if (query->exec())
		{
            int nCount=0;

            // get the 5 (and ONLY 5) denomination values.
            while (ok && nCount<5 && query->getRow())
            {
                ok = query->getData(1, &DenomValues[nCount++]);                    
            }

            if(nCount!=5)
            {
                ok=false;
            }
		}
		delete query;
	}
	delete conn;

	return ok ? TrackSQL::NoError : TrackSQL::ExecFailed;
}

#ifdef FORCED_KENO
int32 KenoSQL::getForcedResults(const PID& pid, int32 gameId, String& results)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;
	int32 sqlResult = TrackSQL::ExecFailed;

	conn = tracker->getConn();
	if (conn)
	{
		query = conn->query();
		if (query)
		{
			query->define("exec [QATestTools_NonProd].[dbo].pub_getKenoForcedResults ");
			query->addParam(pid);
			query->addParam(gameId);

			if (query->exec())
			{
				if (query->getRow())
				{
					ok        = query->getData(1, results);
					sqlResult = ok ? TrackSQL::NoError : TrackSQL::ExecFailed;
				}
				else
					sqlResult = TrackSQL::NoError;
			}
			delete query;
		}
		delete conn;
	}
	else
		sqlResult = TrackSQL::NoConnection;

	return sqlResult;
}
#endif
